﻿namespace NJQuery {
	using System;
	using System.Web.UI;
	using System.Collections.Generic;

	/// <summary>
	/// Server control that allows the <see cref="Page"/> developer to control where the <see cref="Manager"/> places stylesheets.
	/// This allows developers to place more specific stylesheet references after the control in order for their selectors to override the behavior in the standard jQuery widget stylesheets and themes.
	/// This also prevents the Manager control from having to modify the header's controls collection which allows the page developer to include inline code tags.
	/// </summary>
	[ParseChildren(true), PersistChildren(false)]
	public class StyleLinks : Control {


		#region Static Methods: Protected helpers

		/// <summary>
		/// Sets the <see cref="StyleLinks"/> into the page's items dictionary.
		/// </summary>
		/// <param name="page">The <see cref="Page"/> the rendering control resides within.</param>
		/// <param name="value">The jQuery <see cref="StyleLinks"/> control to place into the items dictionary.</param>
		protected static void Set(Page page, StyleLinks value) {
			if(page == null) throw new ArgumentNullException("page");
			if(value == null) throw new ArgumentNullException("value");

			page.Items[typeof(StyleLinks)] = value;
		}

		#endregion


		#region Static Methods: Public

		/// <summary>
		/// Returns the single instance of the <see cref="StyleLinks"/> control if present.
		/// </summary>
		/// <param name="page">The <see cref="Page"/> the rendering control resides within.</param>
		/// <returns>The single instance of the jQuery <see cref="StyleLinks"/> control if present, otherwise null.</returns>
		/// <exception cref="ArgumentNullException">A page reference is required.</exception>
		public static StyleLinks GetCurrent(Page page) {
			if(page == null) throw new ArgumentNullException("page");

			return page.Items[typeof(StyleLinks)] as StyleLinks;
		}

		#endregion


		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="StyleLinks"/> class.
		/// </summary>
		public StyleLinks() { }

		#endregion


		#region Methods: Rendering hooks

		/// <summary>
		/// Raises the <see cref="Control.Init"/> event.
		/// </summary>
		/// <param name="e">The <see cref="EventArgs"/> object that contains the event data.</param>
		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			if(DesignMode) return;

			if(GetCurrent(Page) != null) throw new InvalidOperationException("Page can contain only one instance of " + typeof(StyleLinks).FullName + ".");
			Set(Page, this);
		}

		/// <summary>
		/// Sends server control content to a provided <see cref="HtmlTextWriter"/> object, which writes the content to be rendered to the client.
		/// This method is used primarily by control developers.
		/// </summary>
		/// <param name="writer">A <see cref="HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>
		protected override void Render(HtmlTextWriter writer) {
			if(writer == null) throw new ArgumentNullException("writer");

			Manager manager = Manager.GetCurrent(Page);

			foreach(string styleUrl in manager.RegisteredStyleUrls) {
				writer.WriteLine();
				writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
				writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
				writer.AddAttribute(HtmlTextWriterAttribute.Href, styleUrl);
				writer.RenderBeginTag(HtmlTextWriterTag.Link);
				writer.RenderEndTag();
			}

			writer.WriteLine();
			writer.AddAttribute(HtmlTextWriterAttribute.Name, manager.VersionMetaName);
			writer.AddAttribute(HtmlTextWriterAttribute.Content, manager.Version.ToString());
			writer.RenderBeginTag(HtmlTextWriterTag.Meta);
			writer.RenderEndTag();

			writer.WriteLine();

		}

		#endregion


	}

}